﻿#include "customrectitem.h"

#include <QPen>
#include <QBrush>
#include <QDebug>

CustomRectItem::CustomRectItem(const QRectF &rect, QGraphicsItem *parent)
    : QGraphicsObject(parent), m_rect(rect), m_isSelected(false), m_isEditable(false), m_currentHandle(None)
{
    // 默认情况下，Item是可选的，但不是可移动的
    setFlags(ItemIsSelectable | ItemSendsGeometryChanges);
    setAcceptHoverEvents(true);
}

void CustomRectItem::setEditable(bool editable)
{
    // 在改变任何会影响 boundingRect 的状态之前调用
    prepareGeometryChange();

    m_isEditable = editable;
    // 动态设置 ItemIsMovable 标志
    setFlag(ItemIsMovable, editable);
    update(); // 重新绘制以显示/隐藏手柄
}

bool CustomRectItem::isEditable() const
{
    return m_isEditable;
}


QRectF CustomRectItem::boundingRect() const
{
    // 如果在编辑模式，为手柄留出额外空间
    if (m_isEditable) {
        return m_rect.adjusted(-10, -10, 10, 10);
    }
    return m_rect;
}

void CustomRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    QPen pen;
    pen.setColor(m_isSelected ? Qt::red : Qt::yellow); // 颜色仍然由选中状态决定
    pen.setWidth(2);
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);
    painter->drawRect(m_rect);

    // 只有在编辑模式下才绘制8个缩放手柄
    if (m_isEditable) {
        painter->setPen(Qt::black);
        painter->setBrush(Qt::black);
        for (int i = TopLeft; i <= BottomRight; ++i) {
            painter->drawRect(handleRect(static_cast<Handle>(i)));
        }
    }
}

void CustomRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        // 只有在编辑模式下才检查是否点击了手柄
        if (m_isEditable) {
            m_dragStart = event->pos();
            for (int i = TopLeft; i <= BottomRight; ++i) {
                if (handleRect(static_cast<Handle>(i)).contains(event->pos())) {
                    m_currentHandle = static_cast<Handle>(i);
                    // 阻止事件继续传播，避免触发移动
                    event->accept();
                    return;
                }
            }
        }
    }
    // 其他情况（非编辑模式下点击，或在编辑模式下未点击手柄）
    // 将事件传递给基类处理（例如，切换选中状态或移动）
    QGraphicsObject::mousePressEvent(event);
}

void CustomRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    // 只有在编辑模式且已选中一个手柄时才处理缩放
    if (m_isEditable && m_currentHandle != None) {
        prepareGeometryChange();
        QRectF newRect = m_rect;
        QPointF delta = event->pos() - m_dragStart;

        switch (m_currentHandle) {
            case TopLeft: newRect.setTopLeft(m_rect.topLeft() + delta); break;
            case Top: newRect.setTop(m_rect.top() + delta.y()); break;
            case TopRight: newRect.setTopRight(m_rect.topRight() + delta); break;
            case Left: newRect.setLeft(m_rect.left() + delta.x()); break;
            case Right: newRect.setRight(m_rect.right() + delta.x()); break;
            case BottomLeft: newRect.setBottomLeft(m_rect.bottomLeft() + delta); break;
            case Bottom: newRect.setBottom(m_rect.bottom() + delta.y()); break;
            case BottomRight: newRect.setBottomRight(m_rect.bottomRight() + delta); break;
            default: break;
        }

        if (newRect.width() > 5 && newRect.height() > 5) {
             m_rect = newRect.normalized();
             m_dragStart = event->pos();
        }
        update();
    } else {
        // 如果不是在缩放，则将事件传递给基类处理（例如移动）
        QGraphicsObject::mouseMoveEvent(event);
    }
}

void CustomRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    m_currentHandle = None;
    QGraphicsObject::mouseReleaseEvent(event);
}

void CustomRectItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    // 只有在编辑模式下才改变光标
    if (m_isEditable) {
        for (int i = TopLeft; i <= BottomRight; ++i) {
            if (handleRect(static_cast<Handle>(i)).contains(event->pos())) {
                setHandleCursor(static_cast<Handle>(i));
                return;
            }
        }
    }
    setCursor(Qt::ArrowCursor);
}

QVariant CustomRectItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemSelectedChange && scene()) {
        m_isSelected = value.toBool();
        // 当矩形失去选择时，自动退出编辑模式
        if (!m_isSelected && m_isEditable) {
            setEditable(false);
        }
        update();
    }
    return QGraphicsObject::itemChange(change, value);
}

QRectF CustomRectItem::handleRect(Handle handle) const
{
    qreal size = 8.0;
    QPointF point;
    switch (handle) {
        case TopLeft:     point = m_rect.topLeft(); break;
        case Top:         point = QPointF(m_rect.center().x(), m_rect.top()); break;
        case TopRight:    point = m_rect.topRight(); break;
        case Left:        point = QPointF(m_rect.left(), m_rect.center().y()); break;
        case Right:       point = QPointF(m_rect.right(), m_rect.center().y()); break;
        case BottomLeft:  point = m_rect.bottomLeft(); break;
        case Bottom:      point = QPointF(m_rect.center().x(), m_rect.bottom()); break;
        case BottomRight: point = m_rect.bottomRight(); break;
        case None:        return QRectF();
    }
    return QRectF(point.x() - size/2, point.y() - size/2, size, size);
}

void CustomRectItem::setHandleCursor(Handle handle)
{
    switch (handle) {
        case TopLeft: case BottomRight: setCursor(Qt::SizeFDiagCursor); break;
        case TopRight: case BottomLeft: setCursor(Qt::SizeBDiagCursor); break;
        case Top: case Bottom: setCursor(Qt::SizeVerCursor); break;
        case Left: case Right: setCursor(Qt::SizeHorCursor); break;
        default: setCursor(Qt::ArrowCursor); break;
    }
}
